home *** CD-ROM | disk | FTP | other *** search
- /*
- dirent.c -- file system independant directory access routines for MacOS
-
- Copyright (c) 1993 Anthony C. Ard.
-
- This program is free software; you can redistribute it and/or
- modifiy it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <string.h>
- #include <strings.h>
- #include <plstringfuncs.h>
- #include <files.h>
- #include <errors.h>
- #include <errno.h>
- #include <stdlib.h>
- #include "sys_types.h"
- #include "dirent.h"
-
- typedef void *pointer;
-
- #ifndef NULL
- #define NULL 0
- #endif
-
- static int bit( unsigned long op, unsigned long bitnum );
- #define bit(op,bitnum) (int)(op >> bitnum & 0x01UL)
-
- /*
- closedir -- close a directory stream
- */
-
- int closedir( register DIR *dirp )
- {
- if( dirp == NULL || dirp->dd_buf == NULL ) {
- errno = EFAULT;
- return -1; /* invalid pointer */
- }
-
- free( (pointer)dirp->dd_buf );
- free( (pointer)dirp );
- return NULL;
- }
-
- /*
- opendir -- open a directory stream
- */
-
- DIR *opendir( char *dirname )
- {
- register DIR *dirp;
- int err;
- Str255 fname;
- CInfoPBRec myInfo;
-
- strcpy( fname, dirname );
-
- #ifdef DEBUG
- printf( "# opendir: fname = %s\n", fname );
- #endif DEBUG
-
- c2pstr( fname );
-
- myInfo.hFileInfo.ioVRefNum = 0;
- myInfo.hFileInfo.ioFDirIndex = 0;
- myInfo.hFileInfo.ioDirID = 0;
- myInfo.hFileInfo.ioNamePtr = fname;
-
- err = PBGetCatInfoSync( &myInfo );
- if( err != noErr ) {
- switch( err ) {
- case bdNamErr:
- errno = EINVAL;
- break;
- case dirNFErr:
- errno = ENOENT;
- break;
- case fnfErr:
- errno = ENOENT;
- break;
- case ioErr:
- errno = EIO;
- break;
- case nsvErr:
- errno = ENXIO;
- break;
- case paramErr:
- errno = EINVAL;
- break;
- }
- return NULL;
- }
-
- if( !bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ) { /* Check for directory */
- errno = ENOTDIR;
- return NULL; /* not a directory */
- }
-
- if( (dirp = (DIR *)malloc( sizeof(DIR) )) == NULL
- || (dirp->dd_buf = (char *)malloc( (unsigned)DIRBUF )) == NULL ) {
- register int serrno = errno;
- /* errno set to ENOMEM by sbrk() */
-
- if ( dirp != NULL )
- free( (pointer)dirp );
-
- errno = serrno;
- return NULL;
- }
-
- dirp->dd_fd = myInfo.dirInfo.ioDrDirID;
- dirp->dd_loc = 1; /* Start of first entry in directory */
- dirp->dd_size = myInfo.dirInfo.ioDrNmFls; /* Max number of entries */
-
- return dirp;
- }
-
- /*
- readdir -- read next entry from a directory stream
- */
-
- struct dirent *readdir( register DIR *dirp )
- {
- register struct dirent *dp;
-
- int err;
- Str255 fname;
- CInfoPBRec myInfo;
-
- if( dirp == NULL || dirp->dd_buf == NULL ) {
- errno = EFAULT;
- return NULL; /* invalid pointer */
- }
-
- myInfo.hFileInfo.ioNamePtr = fname;
-
- do {
- myInfo.hFileInfo.ioVRefNum = 0;
- myInfo.hFileInfo.ioFDirIndex = dirp->dd_loc;
- myInfo.hFileInfo.ioDirID = dirp->dd_fd;
- fname[0] = 0;
-
- err = PBGetCatInfoSync( &myInfo );
- if( err != noErr ) {
- switch( err ) {
- case bdNamErr:
- errno = EINVAL;
- break;
- case dirNFErr:
- errno = ENOENT;
- break;
- case fnfErr:
- errno = ENOENT;
- break;
- case ioErr:
- errno = EIO;
- break;
- case nsvErr:
- errno = ENXIO;
- break;
- case paramErr:
- errno = EINVAL;
- break;
- }
- return NULL;
- }
-
- dp = (struct dirent *)dirp->dd_buf;
-
- dp->d_ino = myInfo.hFileInfo.ioDirID;
- dp->d_off = dirp->dd_loc;
- dp->d_reclen = 1;
- PLstrcpy( dp->d_name, myInfo.hFileInfo.ioNamePtr );
- p2cstr( dp->d_name );
- dirp->dd_loc++;
-
- } while( bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ); /* Skip subdirectories */
-
- return dp;
- }
-
- /*
- rewinddir -- rewind a directory stream
- */
-
- void rewinddir( register DIR *dirp )
- {
- if( dirp == NULL || dirp->dd_buf == NULL ) {
- errno = EFAULT;
- return; /* invalid pointer */
- }
-
- dirp->dd_loc = 1; /* First entry in directory */
- }
-
- /*
- seekdir -- reposition a directory stream
- */
-
- void seekdir( register DIR *dirp, register off_t loc )
- {
- if( dirp == NULL || dirp->dd_buf == NULL ) {
- errno = EFAULT;
- return; /* invalid pointer */
- }
-
- if ( loc > dirp->dd_size ) {
- errno = EINVAL;
- return; /* invalid argument */
- }
-
- if( loc == 0 ) loc = 1;
- dirp->dd_loc = loc;
- }
-
- /*
- telldir -- report directory stream position
- */
-
- off_t telldir( DIR *dirp )
- {
- if( dirp == NULL || dirp->dd_buf == NULL ) {
- errno = EFAULT;
- return -1; /* invalid pointer */
- }
-
- return dirp->dd_loc;
- }
-